package ws
import (
	"nightowl/logger"
	"net/http"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"sync"
)
const(
	LOG_MAX_LINE_LENGTH = 1024*1024*64
)
const(
	MSG_TYPE_REQUEST_LOG = "REQUEST_LOG"
)
type RequestLogArg struct {
	ClientID string `json:"clientId"` //clientId
	StepId  uint64 `json:"stepId"` //要读取哪个日志文件
}
type MessageCmd struct{
	Type string `json:"type"` //type
	ClientID string `json:"clientId"` //type
	Args string `json:"args"`
}
var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		return true // 生产环境应限制来源
	},
}
type LogWebsocket struct{
	Conn   *websocket.Conn //socket 连接
	ClientID string
	Clients    map[string]*LogClient //客户端请求管理
	ClientsMu  sync.RWMutex
	Data   chan []byte //数据通道，socket接收到数据后发送出去
}
func NewLogWebsocket() *LogWebsocket {
	return &LogWebsocket{
		Data: make(chan []byte, LOG_MAX_LINE_LENGTH),
	}
}
func (socket *LogWebsocket) Connect(c *gin.Context){
	// 升级HTTP连接到WebSocket
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		c.AbortWithError(http.StatusBadRequest, err)
		return
	}
	// 关闭连接
	defer socket.Close()
	 
	socket.Conn = conn
	//连接后初始化clients
	socket.Clients = make(map[string]*LogClient)
	go socket.Send()
	socket.Read()
}
func (socket *LogWebsocket)Close(){
	logger.Info("LogWebsocket|conn closed...")
	// TODO://处理其它逻辑
	close(socket.Data)
	socket.Conn.Close()
}
/**
 * 
 * 读取客户端发送的消息
 */
func (socket *LogWebsocket) Read() {
	for {
		_, msg, err := socket.Conn.ReadMessage()
		if err != nil {
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
				logger.Error("客户端 %s 异常断开: %v", socket.ClientID, err)
			}
			break
		}
		
		// 处理客户端指令
		logger.Info("receive msg:%s", msg)
		var msgCmd = MessageCmd{}
		if err := json.Unmarshal(msg, &msgCmd); err != nil || msgCmd.Type == "" {
			logger.Error("parse msg error")
			return
		}
		if len(msgCmd.ClientID) == 0{
			socket.ClientID = msgCmd.ClientID
		}
		//如果请求的指令是获取日志
		if msgCmd.Type == MSG_TYPE_REQUEST_LOG{
			var requestLogArg = RequestLogArg{}	
			if err := json.Unmarshal([]byte(msgCmd.Args), &requestLogArg); err != nil {
				logger.Error("parse msg.args error")
				return
			}
			if len(requestLogArg.ClientID) == 0{
				requestLogArg.ClientID = msgCmd.ClientID
			}
			//调用读取日志功能			
			go func(){
				logReader := NewStepRunLogReader(requestLogArg)
				logReader.ReadLogs(socket.Data)
			}()
		}
	}
}
/**
 * 分拣消息 
 * 通过socket.Data通道接收到数据，然后向客户端发送信息
 */
func (socket *LogWebsocket) Send() {	
	for {
		select {
		case message, ok := <-socket.Data:
			if !ok {
				// 通道关闭
				socket.Conn.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}			
			if err := socket.Conn.WriteMessage(websocket.TextMessage, message); err != nil {
				return
			}
		}
	}
}
/**
 * 建立websocket
 */
func HandleWebSocket(c *gin.Context, manager *LogClientManager) {
	// 升级HTTP连接到WebSocket
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		c.AbortWithError(http.StatusBadRequest, err)
		return
	}
	// 首次读取客户端发送的初始化消息(包含clientID)
	_, msg, err := conn.ReadMessage()
	if err != nil {
		conn.Close()
		return
	}
	var msgCmd = MessageCmd{}
	if err := json.Unmarshal(msg, &msgCmd); err != nil || msgCmd.Type == "" {
		logger.Error("parse msg error:%s", err)
		conn.WriteMessage(websocket.CloseMessage, 
			websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, "msgCmd.Type"))
		conn.Close()
		return
	}
	var requestLogArg = RequestLogArg{}	
	if err := json.Unmarshal([]byte(msgCmd.Args), &requestLogArg); err != nil || requestLogArg.ClientID == "" {
		logger.Error("parse msg.args error:%s", err)
		conn.WriteMessage(websocket.CloseMessage, 
			websocket.FormatCloseMessage(websocket.CloseInvalidFramePayloadData, "无效的clientID"))
		conn.Close()
		return
	}
	// 创建客户端
	client := &LogClient{
		ID:     requestLogArg.ClientID,
		Conn:   conn,
		Send:   make(chan []byte, LOG_MAX_LINE_LENGTH),
		LogReader: NewStepRunLogReader(requestLogArg),
	}
	
	// 注册客户端
	manager.register <- client
	
	// 确保连接关闭时注销
	defer func() {
		manager.unregister <- client
		conn.Close()
	}()
	
	// 启动读写协程
	go client.writePump()
	client.readPump()
}

func (c *LogClient) writePump() {
	defer c.Conn.Close()
	
	for {
		select {
		case message, ok := <-c.Send:
			if !ok {
				// 通道关闭
				c.Conn.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}
			
			if err := c.Conn.WriteMessage(websocket.TextMessage, message); err != nil {
				return
			}
		}
	}
}

func (c *LogClient) readPump() {
	defer c.Conn.Close()
	
	for {
		_, msg, err := c.Conn.ReadMessage()
		if err != nil {
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
				logger.Error("客户端 %s 异常断开: %v", c.ID, err)
			}
			break
		}
		
		// 处理客户端指令
		// c.LogReader.HandleCommand(message)
		logger.Info("receive msg:%s", msg)
		var msgCmd = MessageCmd{}
		if err := json.Unmarshal(msg, &msgCmd); err != nil || msgCmd.Type == "" {
			logger.Error("parse msg error")
			return
		}
		var requestLogArg = RequestLogArg{}	
		if err := json.Unmarshal([]byte(msgCmd.Args), &requestLogArg); err != nil || requestLogArg.ClientID == "" {
			
			logger.Error("parse msg.args error")
			return
		}
	}
}